// ==UserScript==
// @name         采集全部商品
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.walmart.com/*
// @icon         https://www.google.com/s2/favicons?domain=walmart.com
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @require      https://gitee.com/great-pacey/tools/raw/master/table2excel.js
// @grant        GM_registerMenuCommand
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @updateURL    https://gitee.com/great-pacey/tampermonkey/raw/master/collect.seller.user.js
// ==/UserScript==
/* global $ */

(function () {
	const DATA = unsafeWindow.__NEXT_DATA__;
	const sellerId = getSellerId();
	const pre_url = `https://www.walmart.com/seller/${sellerId}`;
	GM_registerMenuCommand('抓取店铺商品', run);
	let products = [], productIds = [];

	function formatProduct(p) {
		const { image, flag, usItemId } = p;
		return {
			productId: usItemId,
			price: p.price || p.priceInfo.minPriceForVariant,
			reviews: p.numberOfReviews,
			promote: flag,
			title: p.name,
			image,
		}
	}

	async function wait() {
		return new Promise(resolve => setTimeout(resolve, 500));
	}

	async function run() {
		let ids = await getProductIds();
		let i = 0;
		if (!appendIds(ids)) return;
		while(i < productIds.length) {
			await wait();
			ids = await getProductIds(productIds[i++]);
			appendIds(ids);
		}
		exportExcel();
	}

	function exportExcel() {
		genTable();
		$('#tb').table2excel({ filename: `${sellerId} - 店铺全部商品`});
	}

	function genTable() {
		const tb = unsafeWindow.document.createElement('table');
		tb.setAttribute("id", "tb");
		tb.style.display = 'none';
		let html = '<tr><th>No</th><th>productId</th><th>price</th><th>reviews</th><th>promote</th><th>title</th><th>主图</th></tr>';
		products.forEach((p, i) => {
			html += `<tr><td>${i + 1}</td><td>${p.productId}</td><td>${p.price}</td><td>${p.reviews}</td><td>${p.promote}</td><td>${p.title}</td><td>${p.image}</td></td></tr>`;
		});
		html += '</table>';
		tb.innerHTML = html;
		unsafeWindow.document.body.appendChild(tb);
		return tb;
	}

	function appendIds(ids) {
		const newIds = ids.filter(id => !productIds.includes(id));
		const hasRew = !!newIds.length;
		if (hasRew) productIds = productIds.concat(newIds);
		return hasRew;
	}

	function getProductIds(productId) {
		const url = productId ? `${pre_url}?itemId=${productId}&pageName=item` : pre_url;
		return new Promise((resolve, reject) => {
			GM_xmlhttpRequest({
				method: "GET",
				url,
				onload: function (res) {
					try {
						const reg = /<script\b(?:\s+[^>]*)?__NEXT_DATA__(?:[^>]*)?>(.*?)<\/script\s*>/i;
						const text = res.responseText.match(reg)[1];
						const ps = JSON.parse(text).props.pageProps.initialData.data.contentLayout.modules[1].configs.products;
						const result = ps.map(i => i.usItemId);
						products = products.concat(ps.map(p => formatProduct(p)).filter(p => !productIds.includes(p.productId)));
						console.log(`已采集${productIds.length}个商品`);
						resolve(result);
					} catch(err){
						console.log(err);
						console.log(res.responseText);
						reject();
					}
				}
			});
		})
	}

	function getSellerId() {
		return isItemPage() ? DATA.props.pageProps.initialData.data.product.catalogSellerId : DATA.query.id;
	}

	function isItemPage() {
		return !unsafeWindow.location.href.includes('/seller/');
	}
})()